<template>
	<div class="map-container">
		<!-- 头部工具栏    -->
		<div class="headerToolbar">
			<!-- 保存    -->
			<button @click="save">保存</button>
			<!-- 预览   -->
			<button @click="preview">预览</button>
		</div>
		<div v-if="show3dPreview" class="preview-modal">
			<div class="preview-content">
				<button @click="show3dPreview = false" class="close-btn">
					关闭
				</button>
				<preview3D
					v-if="show3dPreview"
					:features="features"
					:height="8"
					:map-center="mapCenter"
				/>
			</div>
		</div>
		<div class="canvas-container">
			<div class="toolbar">
				<button @click="activateDraw('Polygon', 'floor')">地板</button>

				<button @click="activateDraw('Polygon', 'room')">多边形</button>
				<button @click="activateDraw('Circle', 'room')">圆形</button>
				<button @click="activateDraw('LineString', 'path')">
					道路
				</button>
				<button @click="clearAll">清除</button>
				<button @click="clearRoads">清除道路</button>
				<h3>图层管理</h3>
				<div v-for="(layer, index) in layers" :key="index">
					<label>
						<input
							type="checkbox"
							v-model="layer.visible"
							@change="toggleLayerVisibility(layer)"
						/>
						{{ layer.name }}
					</label>
				</div>
			</div>
			<div
				id="map-container"
				style="width: 100%; height: 100%"
				@contextmenu="handleContextMenu"
			></div>
		</div>
	</div>
</template>
<script>
import "ol/ol.css";
import { Map, View } from "ol";
import { OSM, Vector as VectorSource } from "ol/source";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { Draw } from "ol/interaction";
import { Image as ImageLayer } from "ol/layer";
import { ImageStatic } from "ol/source";
import preview3D from "./preview3D.vue";
import proj4 from "proj4";
import ThreePathfindingDemo from "./aaaa";

export default {
	components: { preview3D, ThreePathfindingDemo },
	data() {
		return {
			mapCenter: [12919577, 4520025], // 中心点坐标
			show3dPreview: false,
			map: null,
			draw: null,
			features: [],
			vectorSource: null, // 初始化vectorSource
			vectorLayer: null, // 初始化vectorLayer
			layers: [
				{ name: "底图层", layer: null, visible: true, type: "base" },
				{ name: "地板层", layer: null, visible: true, type: "floor" },
				{ name: "面层", layer: null, visible: true, type: "room" },
				{ name: "标注层", layer: null, visible: true, type: "label" },
				{ name: "图标层", layer: null, visible: true, type: "icon" },
				{
					name: "通行节点层",
					layer: null,
					visible: true,
					type: "node",
				},
				{ name: "路径层", layer: null, visible: true, type: "path" },
			],
			//绘制时的数据
			drawData: {
				//绘制的类型
				type: "Polygon",
				//绘制的图层
				layer: "room",
			},
		};
	},
	mounted() {
		this.initMap();
	},
	watch: {
		features: {
			handler(newVal, oldVal) {
				console.log(newVal, oldVal);
			},
		},
	},
	methods: {
		clearRoads() {
			const pathLayer = this.layers.find(
				(layer) => layer.type === "path"
			);
			if (pathLayer && pathLayer.layer) {
				pathLayer.layer.getSource().clear();
				this.features = this.features.filter(
					(f) => f.layerType !== "path"
				);
			}
		},
		//保存
		save() {
			console.log("save:保存", this.features);
		},
		//预览
		preview() {
			if (!this.features.length) {
				alert("请先绘制图形");
				return;
			}
			this.show3dPreview = true;
			console.log("preview:预览", this.features);
		},
		toggleLayerVisibility(layer) {
			layer.layer.setVisible(layer.visible);
		},
		/**
		 * 开始进行绘制
		 * @param {string} type 绘制类型 Polygon/Circle
		 * @param {string} layerType 图层类型 room/node/path
		 */
		activateDraw(type, layerType) {
			// 添加null检查
			if (this.draw) {
				this.map.removeInteraction(this.draw); // 移除之前的绘制交互
				// this.draw.un("drawend");
			}
			this.drawData.type = type;
			this.drawData.layer = layerType;

			// 创建新实例前初始化
			this.draw = new Draw({
				source: this.vectorSource,
				type: type,
				aaa: "111",
			});
			// 绑定事件
			this.draw.on("drawend", this.handleDrawEnd);
			this.map.addInteraction(this.draw);
		},
		/**
		 * 绘制结束事件处理函数
		 */
		handleDrawEnd(event) {
			const feature = event.feature;
			// 绘制目标图层
			const targetLayerType = this.drawData.layer;
			//绘制的图形
			const type = this.drawData.type;
			//在场景中找到要绘制的图层
			const targetLayer = this.layers.find(
				(layer) => layer.type === targetLayerType
			);
			console.log(targetLayer, "targetLayer", targetLayerType);
			// 检查目标图层是否存在
			if (targetLayer && targetLayerType) {
				// 将特征添加到对应图层的source中
				targetLayer.layer.getSource().addFeature(feature);
				// 保存特征信息
				this.features.push({
					type: type, //绘制类型（多边形、四边形、圆形等）
					coordinates: feature.getGeometry().getCoordinates(), // 坐标数组
					id: Date.now(),
					layerType: targetLayer.type, //属于的图层类型
					isRoad: targetLayerType === "path", //是否是道路
				});
			} else {
				console.log("没有找到对应的图层", targetLayerType);
			}
		},
		clearAll() {
			this.vectorSource.clear();
		},

		initMap() {
			this.vectorSource = new VectorSource();
			this.vectorLayer = new VectorLayer({ source: this.vectorSource });
			// 初始化底图
			const baseLayer = new ImageLayer({
				source: new ImageStatic({
					url: require("@/assets/万柏林.png"),
					// imageExtent: [
					// 	1291.4871528, 451.7113706, 1292.428298, 452.2937609,
					// ],
					// projection: "EPSG:3857",
					imageExtent: [112.45, 37.75, 112.65, 37.85], // 经纬度范围
					projection: "EPSG:4326", // 切换为WGS84
				}),
			});
			// 初始化其他图层
			const floorLayer = new VectorLayer({ source: new VectorSource() });
			const roomLayer = new VectorLayer({ source: new VectorSource() });
			const labelLayer = new VectorLayer({ source: new VectorSource() });
			const iconLayer = new VectorLayer({ source: new VectorSource() });
			const nodeLayer = new VectorLayer({ source: new VectorSource() });
			const pathLayer = new VectorLayer({ source: new VectorSource() });

			// 初始化地图实例，将其赋值给组件的 map 属性
			this.map = new Map({
				// 指定地图要渲染到的 DOM 元素的 ID，这里是 "map-container"
				target: "map-container",
				// 定义地图的图层数组，地图可以包含多个图层，按顺序叠加显示
				layers: [
					baseLayer,
					floorLayer,
					roomLayer,
					labelLayer,
					iconLayer,
					nodeLayer,
					pathLayer,
				],
				// 定义地图的视图，包括地图的中心点和缩放级别
				view: new View({
					// 设置地图的中心点坐标，使用 EPSG:3857 投影坐标系
					center: [112.55, 37.8], // 中心点经纬度
					zoom: 13, // EPSG:4326的zoom范围通常为0-18
					projection: "EPSG:4326",
				}),
			});
			// 保存图层引用
			this.layers[0].layer = this.map.getLayers().item(0);
			this.layers[1].layer = this.map.getLayers().item(1);
			this.layers[2].layer = this.map.getLayers().item(2);
			this.layers[3].layer = this.map.getLayers().item(3);
			this.layers[4].layer = this.map.getLayers().item(4);
			this.layers[5].layer = this.map.getLayers().item(5);
			this.layers[6].layer = this.map.getLayers().item(6);
			// 添加默认交互（关键修复）
			// 此段代码的作用是遍历地图实例 `this.map` 中的所有交互对象。
			// `this.map.getInteractions()` 方法会返回一个包含地图所有交互对象的集合。
			// 接着使用 `forEach` 方法对这个集合中的每个交互对象进行迭代操作。
			// this.map.getInteractions().forEach((interaction) => {
			// 	// 对于每个交互对象，使用 `get("custom")` 方法检查其是否具有名为 "custom" 的属性。
			// 	// 如果该属性存在且为真值，意味着这个交互对象是自定义的交互。
			// 	if (interaction.get("custom")) {
			// 		// 当发现自定义交互对象时，使用 `this.map.removeInteraction(interaction)` 方法将其从地图中移除。
			// 		// 这样可以确保地图中不再存在这些自定义交互，避免不必要的交互影响地图操作。
			// 		this.map.removeInteraction(interaction);
			// 	}
			// });

			// this.initDrawInteraction(vectorSource);
		},
		initDrawInteraction(source) {
			this.draw = new Draw({
				source: source,
				type: "Polygon",
			});
			this.map.addInteraction(this.draw);

			this.draw.on("drawend", (event) => {
				const coords = event.feature.getGeometry().getCoordinates();
				console.log("多边形坐标:", coords);
			});
		},
		//在绘制过程中，如果进行了右键操作，停止并结束绘制
		// 以下说明如何调用 handleContextMenu 方法
		// 1. 在模板中绑定右键菜单事件
		// 在需要监听右键菜单事件的元素上添加 @contextmenu 指令，例如在地图容器上：
		// <div id="map-container" style="width: 100%; height: 100%" @contextmenu="handleContextMenu"></div>

		// 2. 保持原方法实现不变
		handleContextMenu(event) {
			console.log("右键菜单被触发:event:", event);
			event.preventDefault();
			this.map.removeInteraction(this.draw);
			// this.draw.removeLastPoint();
		},
	},
};
</script>
<style scoped>
.map-container {
	width: 100%;
	height: 100vh;
	display: flex;
	flex-direction: column;
}
/* 3D预览弹框样式 */
.preview-modal {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: rgba(0, 0, 0, 0.7);
	display: flex;
	justify-content: center;
	align-items: center;
	z-index: 1000;
}

.preview-content {
	width: 80%;
	height: 80%;
	background: white;
	padding: 20px;
	position: relative;
}

.close-btn {
	position: absolute;
	top: 10px;
	right: 10px;
	padding: 5px 10px;
}
.headerToolbar {
	width: 100%;
	height: 100px;
	background: #e4ebf9;
	display: flex;
}
.canvas-container {
	flex: 1;
	display: flex;
}
.toolbar {
	width: 120px;
	padding: 10px;
	background: #fff;
	box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
}
.layer-control {
	width: 150px;
	padding: 10px;
	background: #fff;
	box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
}
.toolbar {
	width: 120px;
	padding: 10px;
	background: #fff;
	box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
}
button {
	display: block;
	width: 100%;
	margin-bottom: 5px;
}
</style>
